﻿#include "Render.h"
#include "../../common/error.h"
#include "../../common/shader.hpp"
#include "../../common/texture.hpp"
#include "RenderConfig.h"

SceneRender::SceneRender()
{
	m_TextRender = new TextRender();
	m_RenderingQuestion = true;
}

SceneRender::~SceneRender()
{
	ClearBuffers();
	delete m_TextRender;
}

void SceneRender::Init()
{
	// Init Viewport
	int border = 2;
	m_Viewport[VIEWPORT_RACE] = glm::ivec4(border,border,FRAMEBUFFER_SIZE - 2 * border);
	m_Viewport[VIEWPORT_QUESTION] = glm::ivec4(FRAMEBUFFER_SIZE.x + border , border,FRAMEBUFFER_SIZE - 2 * border);

	// Init program
	InitProgram();

	// Init buffers
	InitBuffer();

	// Init Texture
	InitTexture();

}

void SceneRender::Render()
{
	glClear(GL_COLOR_BUFFER_BIT);
	//glClearColor(0.2,0.5,0.5,0.0);

	//RenderBackground();
	RenderSimpleTriangles();

	// Dispaly text
	if(m_RenderingQuestion)
		RenderQuestion();
	else
		RenderStats();

}

void SceneRender::RenderBackground()
{
	// Draw Question board
	SetViewport(VIEWPORT_QUESTION);
	
	glUseProgram(m_QuestionProgram);
	
	glEnableVertexAttribArray(0);
	glBindBuffer(GL_ARRAY_BUFFER,m_VertexBuffers[BUFFER_VERTEX]);
	glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,0,0);

	glEnableVertexAttribArray(1);
	glBindBuffer(GL_ARRAY_BUFFER,m_VertexBuffers[BUFFER_TEXCOORD]);
	glVertexAttribPointer(1,2,GL_FLOAT,GL_FALSE,0,0);

	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D,m_Textures[TEXTURE_QUESTIONBOARD]);
	glUniform1i(m_UniformLocationSampler2D,0);

	glDrawArrays(GL_TRIANGLES,0,6);

	glDisableVertexAttribArray(0);
	glDisableVertexAttribArray(1);

	checkError("RenderBackground");
}

// Test function
void SceneRender::RenderSimpleTriangles()
{
	SetViewport(VIEWPORT_RACE);
	glUseProgram(m_TestProgram);

	glEnableVertexAttribArray(0);
	glBindBuffer(GL_ARRAY_BUFFER,m_VertexBuffers[BUFFER_TRIANGLVERTEX]);
	glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,0,0);

	glDrawArrays(GL_TRIANGLES,0,3);

	glDisableVertexAttribArray(0);
}

void SceneRender::RenderCar()
{

}

void SceneRender::RenderQuestion()
{
	m_TextRender->SetSize(FONT_SIZE_QUESTION);

	glColor3f(1.0,0.0,1.0);
	glWindowPos2d(POS_QUESTIONBOARD.x + POS_OFFSET_QUESTIONHEADER.x,POS_QUESTIONBOARD.y + POS_OFFSET_QUESTIONHEADER.y);
	m_TextRender->RenderWString(m_QuestionHeader);

	glColor3f(1.0,0.5,0.5);
	glWindowPos2d(POS_QUESTIONBOARD.x + POS_OFFSET_QUESTIONTITLE.x,POS_QUESTIONBOARD.y + POS_OFFSET_QUESTIONTITLE.y);
	m_TextRender->RenderWString(m_QuestionTitle);

	glWindowPos2d(POS_QUESTIONBOARD.x + POS_OFFSET_QUESTIONOPTIONA.x,POS_QUESTIONBOARD.y + POS_OFFSET_QUESTIONOPTIONA.y);
	m_TextRender->RenderWString(m_QuestionOptionA);

	glWindowPos2d(POS_QUESTIONBOARD.x + POS_OFFSET_QUESTIONOPTIONB.x,POS_QUESTIONBOARD.y + POS_OFFSET_QUESTIONOPTIONB.y);
	m_TextRender->RenderWString(m_QuestionOptionB);
}

void SceneRender::RenderStats()
{
	m_TextRender->SetSize(FONT_SIZE_STATS);

	glWindowPos2d(POS_QUESTIONBOARD.x + POS_OFFSET_STATHEADER.x,POS_QUESTIONBOARD.y + POS_OFFSET_STATHEADER.y);
	m_TextRender->RenderWString(m_StatHeader);

	glWindowPos2d(POS_QUESTIONBOARD.x + POS_OFFSET_STATTOTAL.x,POS_QUESTIONBOARD.y + POS_OFFSET_STATTOTAL.y);
	m_TextRender->RenderWString(m_StatTotal);

	glWindowPos2d(POS_QUESTIONBOARD.x + POS_OFFSET_STATCORRECT.x,POS_QUESTIONBOARD.y + POS_OFFSET_STATCORRECT.y);
	m_TextRender->RenderWString(m_StatCorrect);

	glWindowPos2d(POS_QUESTIONBOARD.x + POS_OFFSET_STATWRONG.x,POS_QUESTIONBOARD.y + POS_OFFSET_STATWRONG.y);
	m_TextRender->RenderWString(m_StatWrong);

}

void SceneRender::SetQuestionData(std::wstring header, std::wstring title,std::wstring optionA,std::wstring optionB)
{
	m_QuestionHeader = header;
	m_QuestionTitle = title;
	m_QuestionOptionA = optionA;
	m_QuestionOptionB = optionB;

	m_RenderingQuestion = true;
}

void SceneRender::SetStatData(std::wstring header,std::wstring total,std::wstring correct,std::wstring wrong)
{
	m_StatHeader = header;
	m_StatTotal = total;
	m_StatCorrect = correct;
	m_StatWrong = wrong;

	m_RenderingQuestion = false;
}

void SceneRender::InitProgram()
{
	m_QuestionProgram = glCreateProgram();

	SHADER_HPP::CompileShaderFromFile("shader/vs_question.glsl",GL_VERTEX_SHADER,m_QuestionProgram);
	SHADER_HPP::CompileShaderFromFile("shader/fs_question.glsl",GL_FRAGMENT_SHADER,m_QuestionProgram);

	m_UniformLocationSampler2D = glGetUniformLocation(m_QuestionProgram,"gSampler");

	// Test program
	m_TestProgram = glCreateProgram();
	SHADER_HPP::CompileShaderFromFile("shader/vs_triangles.glsl", GL_VERTEX_SHADER, m_TestProgram);
	SHADER_HPP::CompileShaderFromFile("shader/fs_triangles.glsl", GL_FRAGMENT_SHADER, m_TestProgram);

	checkError("InitProgram");

}

void SceneRender::InitBuffer()
{
	glm::vec3 const vertexDate[6] = 
	{
		glm::vec3(-1.0f,-1.0f,-1.0f),
		glm::vec3(-1.0f,1.0f,-1.0f),
		glm::vec3(1.0f,-1.0f,-1.0f),
		glm::vec3(1.0f,-1.0f,-1.0f),
		glm::vec3(1.0f,1.0f,-1.0f),
		glm::vec3(-1.0f,1.0f,-1.0f)
	};

	glm::vec2 const texData[6] =
	{
		glm::vec2(0.0f, 0.0f),
		glm::vec2(0.0f, 1.0f),
		glm::vec2(1.0f, 0.0f),
		glm::vec2(1.0f, 0.0f),
		glm::vec2(1.0f, 1.0f),
		glm::vec2(0.0f, 1.0f)
	};

	glm::vec3 const testVertexData[6]=
	{
		glm::vec3(-0.2f,-0.2f,-0.2f),
		glm::vec3(-0.2f,0.2f,-0.2f),
		glm::vec3(0.2f,-0.2f,-0.2f),
		glm::vec3(0.2f,-0.2f,-0.2f),
		glm::vec3(0.2f,0.2f,-0.2f),
		glm::vec3(-0.2f,0.2f,-0.2f)
	};

	glGenBuffers(BUFFER_COUNT,m_VertexBuffers);
	glBindBuffer(GL_ARRAY_BUFFER,m_VertexBuffers[BUFFER_VERTEX]);
	glBufferData(GL_ARRAY_BUFFER,sizeof(vertexDate),vertexDate,GL_STATIC_DRAW);
	glBindBuffer(GL_ARRAY_BUFFER,0);

	glBindBuffer(GL_ARRAY_BUFFER,m_VertexBuffers[BUFFER_TEXCOORD]);
	glBufferData(GL_ARRAY_BUFFER,sizeof(texData),texData,GL_STATIC_DRAW);
	glBindBuffer(GL_ARRAY_BUFFER,0);

	glBindBuffer(GL_ARRAY_BUFFER,m_VertexBuffers[BUFFER_TRIANGLVERTEX]);
	glBufferData(GL_ARRAY_BUFFER,sizeof(testVertexData),testVertexData,GL_STATIC_DRAW);
	glBindBuffer(GL_ARRAY_BUFFER,0);

	checkError("InitBuffer");
	
}

void SceneRender::InitTexture()
{
	glGenTextures(TEXTURE_COUNT,m_Textures);
	TEXTURE_HPP::ILTex2D(TEX_QUESTIONBOARD,m_Textures[TEXTURE_QUESTIONBOARD]);

	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);

	checkError("InitTexture");
}

void SceneRender::ClearBuffers()
{
	glDeleteBuffers(BUFFER_COUNT,m_VertexBuffers);
	glDeleteProgram(m_QuestionProgram);
	glDeleteProgram(m_RaceProgram);
}

void SceneRender::SetViewport(VIEWPORT port)
{
	glViewport(m_Viewport[port].x,m_Viewport[port].y,m_Viewport[port].z,m_Viewport[port].w);
}